﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.SessionState;
using System.Configuration;
using RN.ERP.Web.ModelService;
using Newtonsoft.Json;
using System.Xml.Linq;
using System.Web.Caching;

namespace RN.ERP.Web.Handlers
{
    /// <summary>
    /// 系统公告
    /// </summary>
    public class SysAnnounce : IHttpHandler, IRequiresSessionState
    {
        #region Params

        private string AppID
        {
            get
            {
                return HttpContext.Current.Application[ApplicationConstant.APPLICATION_ID].ToString();
            }
        }

        private string SysArea
        {
            get
            {
                return ConfigurationManager.AppSettings["sysArea"];
            }
        }

        private SessionUserInfo UserInfo
        {
            get
            {
                if (HttpContext.Current.Session[SessionConstant.SESSION_USERINFO] != null)
                {
                    return (SessionUserInfo)HttpContext.Current.Session[SessionConstant.SESSION_USERINFO];
                }
                return null;
            }
        }
        
        #endregion

        public void ProcessRequest(HttpContext context)
        {
            if (UserInfo != null)
            {
                GetSystemAnnouncement();
            }
        }
        
        /// <summary>
        /// 获取并输出公告
        /// </summary>
        private void GetSystemAnnouncement()
        {
            var list = AnnounceBLL.GetAllAnnounce();
            if (list != null)
            {
                var item = list.Where(i => i.AppID == AppID && i.RoleID == UserInfo.RoleId).FirstOrDefault();
                if (item != null)
                {
                    PrintStr(item.ToString());
                }
            }
        }

        /// <summary>
        /// 输出对象
        /// </summary>
        private void PrintObj(object obj)
        {
            string str = JsonConvert.SerializeObject(obj);
            PrintStr(str);
        }

        /// <summary>
        /// 输出
        /// </summary>
        private void PrintStr(string str)
        {
            HttpContext.Current.Response.Write(str);
            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        public class AnnounceBLL
        {
            private static string CONFIG_FILE_PATH = "AnnounceSource.xml";
            private const string CACHE_KEY = "SYS_ANNOUNCE";
            private static readonly object _lock = new object();

            public static List<Announce> GetAllAnnounce()
            {
                List<Announce> fileList = HttpContext.Current.Cache[CACHE_KEY] as List<Announce>;
                if (fileList == null)
                {
                    lock (_lock)
                    {
                        fileList = HttpContext.Current.Cache[CACHE_KEY] as List<Announce>;
                        if (fileList == null)
                        {
                            fileList = GetAnnouncesFromFile();
                            CacheDependency cd = new CacheDependency(AppDomain.CurrentDomain.BaseDirectory + CONFIG_FILE_PATH);
                            HttpContext.Current.Cache.Insert(CACHE_KEY, fileList, cd);
                        }
                    }
                }
                return fileList;
            }

            /// <summary>
            /// 从配置文件读取公告信息
            /// </summary>
            /// <returns></returns>
            private static List<Announce> GetAnnouncesFromFile()
            {
                XDocument doc = XDocument.Load(AppDomain.CurrentDomain.BaseDirectory + CONFIG_FILE_PATH);
                List<Announce> anns = new List<Announce>();
                if (doc != null)
                {
                    anns = doc.Root.Elements("item")
                        .Select<XElement, Announce>(fileEle => new Announce
                        {
                            AppID = fileEle.Attribute("AppID").Value,
                            Type = fileEle.Attribute("Type").Value,
                            Title = fileEle.Attribute("Title").Value,
                            Url = fileEle.Attribute("Url").Value,
                            Width = fileEle.Attribute("Width").Value,
                            Height = fileEle.Attribute("Height").Value,
                            StartDate = fileEle.Attribute("StartDate").Value,
                            EndDate = fileEle.Attribute("EndDate").Value,
                            RoleID = fileEle.Attribute("RoleID").Value,
                            IsDel = fileEle.Attribute("IsDel").Value,
                            Content = fileEle.Value
                        }).Where(i => i.IsDel == "false"
                            && DateTime.Parse(i.StartDate) < DateTime.Now
                            && DateTime.Parse(i.EndDate) > DateTime.Now).ToList();
                }
                return anns;
            }
        }

        public class Announce
        {
            public string AppID { set; get; }
            public string Type { set; get; }
            public string Title { set; get; }
            public string Url { set; get; }
            public string Width { set; get; }
            public string Height { set; get; }
            public string StartDate { set; get; }
            public string EndDate { set; get; }
            public string IsDel { set; get; }
            public string RoleID { set; get; }
            public string Content { set; get; }

            public override string ToString()
            {
                object obj = new { };
                if (this.Type == "html")
                {
                    string content = this.Content.Replace("{{", "<").Replace("}}",">");
                    obj = new
                    {
                        Type = "html",
                        Content = content
                    };
                }
                else if (this.Type == "Page")
                {
                    obj = new
                    {
                        Type = "page",
                        Url = this.Url,
                        Width=this.Width,
                        Height = this.Height
                    };
                }
                return JsonConvert.SerializeObject(obj);
            }
        }
    }
}